﻿using System.Text;
using System.Collections.Generic;
using Microsoft.SqlServer.Management.Smo;
using NazTek.Utility.Extensions.SqlObject;
using Settings = NazTek.Utility.Properties.Settings;

namespace NazTek.Utility
{
    /// <summary>
    /// Encapsulates unique key indexes for building generating schema updating dynamic SQL.
    /// </summary>
    public class UniqueKeyIndex
    {
        /// <summary>
        /// Gets names of columns participating in the index.
        /// </summary>
        public virtual string ColumnNames { get { return null; } }
        /// <summary>
        /// Gets names of columns and their data types participating in the index.
        /// </summary>
        public virtual string ColumnNamesWithTypes { get { return null; } }
        /// <summary>
        /// Gets inner join string for columns participating in the index.
        /// </summary>
        public virtual string TableJoinString { get { return null; } }
    }
    /// <summary>
    /// Encapsulates unique key indexes for building generating schema updating dynamic SQL, for single column index.
    /// </summary>
    public sealed class UniqueSimpleKeyIndex : UniqueKeyIndex
    {
        /// <summary>
        /// Gets the index column name.
        /// </summary>
        public override string ColumnNames
        {
            get { return Column.Key; }
        }
        /// <summary>
        /// Gets the index column with data type name.
        /// </summary>
        public override string ColumnNamesWithTypes
        {
            get { return string.Format("{0} {1}", Column.Key, Column.Value); }
        }
        /// <summary>
        /// Gets inner join string for the index column.
        /// </summary>
        public override string TableJoinString
        {
            get { return string.Format("src.{0}=ids.{0}", Column.Key); }
        }
        /// <summary>
        /// Stores the column as a key/value pair, where key is column name and value is it's data type name.
        /// </summary>
        /// <param name="column">Provides key/value pair.</param>
        public UniqueSimpleKeyIndex(Column column)
        {
            Column = new KeyValuePair<string, string>(column.Name, column.GetDataTypeName());
        }
        /// <summary>
        /// Gets/sets name/data type as key/value pair.
        /// </summary>
        private KeyValuePair<string, string> Column { get; set; }
    }
    /// <summary>
    /// Encapsulates unique key indexes for building generating schema updating dynamic SQL, for multi column index.
    /// </summary>
    public sealed class UniqueComplexKeyIndex : UniqueKeyIndex
    {
        /// <summary>
        /// Gets index column names, separated by <see cref="NazTek.Utility.Properties.Settings.Separator"/>.
        /// </summary>
        public override string ColumnNames
        {
            get
            {
                var builder = new StringBuilder();
                ColumnList.ForEach(c => builder.AppendFormat("{0}{1}", c.Key, Settings.Default.Separator));
                return builder.ToString().TrimEnd(Settings.Default.Separator.ToCharArray());
            }
        }
        /// <summary>
        /// Gets index columns with data type names, separated by <see cref="NazTek.Utility.Properties.Settings.Separator"/>.
        /// </summary>
        public override string ColumnNamesWithTypes
        {
            get
            {
                var builder = new StringBuilder();
                ColumnList.ForEach(
                    c => builder.AppendFormat("{0} {1}{2}", c.Key, c.Value, Settings.Default.Separator));
                return builder.ToString().TrimEnd(Settings.Default.Separator.ToCharArray());
            }
        }
        /// <summary>
        /// Gets inner join string for the index columns, separated by <see cref="Joiner"/>.
        /// </summary>
        public override string TableJoinString
        {
            get
            {
                var builder = new StringBuilder();
                ColumnList.ForEach(c => builder.AppendFormat("src.{0}=ids.{0}{1}", c.Key, Joiner));
                return builder.ToString().TrimEnd(Joiner.ToCharArray());
            }
        }
        /// <summary>
        /// Stores index columns as a key/value pairs, where keys are column names and values are their data type names.
        /// </summary>
        /// <param name="columnList">Provides key/value pairs.</param>
        public UniqueComplexKeyIndex(List<Column> columnList)
        {
            ColumnList = new List<KeyValuePair<string, string>>();
            columnList.ForEach(
                column => ColumnList.Add(new KeyValuePair<string, string>(column.Name, column.GetDataTypeName())));
        }
        /// <summary>
        /// Gets/sets name/data type as key/value pairs.
        /// </summary>
        private List<KeyValuePair<string, string>> ColumnList { get; set; }
        /// <summary>
        /// Column-wise inner join concatenate string.
        /// </summary>
        private const string Joiner = " AND ";
    }
}
